import type { Request, Response } from "express";
import type { ArrayCheck, BaseCheck, ObjectCheck } from "./typing";
import { logger } from "@/utils/log"; // 日志方法
import { isNumber } from "lodash-es";
export const executeCommand = async (
  req: Request,
  res: Response,
  callback: () => Promise<any>
) => {
  try {
    await callback();
  } catch ({ message, error }) {
    logger.error({ message, error, res });
  }
};
// 正常返回--200
// 参数错误--205
// token错误--401
// 其他错误--500
// 逻辑执行错误--203
// 文件上传错误--202
export type Code = 200 | 205 | 203 | 401 | 500 | 202;

// 基本响应
export const response = (
  res: Response,
  code: Code,
  result?: any,
  message?: string
) => {
  const success = code == 200;
  const messageMap = {
    200: "操作成功",
    401: "访问该资源需要完全身份认证",
    205: "参数错误",
    500: "服务器内部错误",
    203: "逻辑错误",
  };
  const json = { code, result, message, success };
  message = message || messageMap[code];
  // logger.log("响应：");
  // logger.log(json);
  res.json(json);
};

const baseTypeMap = {
  string: "字符串",
  number: "数字",
  boolean: "布尔值",
};

// 基本数据校验
export const validateBase: (
  check: BaseCheck,
  value: any,
  name: string
) => string = (check, value, name = "参数") => {
  const { regExp, message, type, canNull } = check;
  if (canNull && !value) return "";
  if (type !== "boolean" && !canNull && !value) return `${name}不能为空`;
  else if (
    (type === "number" && typeof value === "string" && !isNumber(value)) ||
    typeof value !== type
  )
    return `${name}必须是${baseTypeMap[type]}`;
  else if (regExp && !regExp.test(value)) return message || `${name}校验失败`;
  return "";
};

// 数组校验
export const validateArray: (
  check: ArrayCheck,
  arr: any,
  name: string
) => string = (check, arr, name = "参数") => {
  const { type, arrayCheck, objectCheck, baseCheck, length } = check;
  if (!Array.isArray(arr)) return `${name}必须是数组`;
  else if (length && arr.length !== length) return `${name}长度应为${length}`;
  for (const value of arr) {
    if (type === "array") {
      if (!Array.isArray(value)) return `${name}必须是数组`;
      else if (!arrayCheck) return "请添加数组配置";
      const result = validateArray(arrayCheck, value, name + "数组项");
      if (result) return result;
    } else if (type === "object") {
      if (value.toString() !== "[object Object]") return `${name}必须是对象`;
      else if (!objectCheck) return "请添加对象配置";
      const result = validateObject(objectCheck, value);
      if (result) return result;
    } else {
      if (!baseCheck) return "请添加基本类型配置";
      const result = validateBase(baseCheck, value, name + "数组项");
      if (result) return result;
    }
  }
  return "";
};

// 对象校验
export const validateObject: (checkList: ObjectCheck[], obj: any) => string = (
  checkList,
  obj
) => {
  if (obj.toString() !== "[object Object]") return "参数必须是对象";
  for (const check of checkList) {
    const { field, type, required, arrayCheck, objectCheck, baseCheck } = check;
    const haveField = field in obj;
    const value = obj[field];
    if (required && !haveField) return `${field}字段缺失`;
    if (!haveField) continue;
    if (type === "array") {
      if (!arrayCheck) return "请添加数组配置";
      const result = validateArray(arrayCheck, value, field);
      if (result) return result;
    } else if (type === "object") {
      if (!objectCheck) return "请添加对象配置";
      const result = validateObject(objectCheck, value);
      if (result) return result;
    } else {
      if (!baseCheck) return "请添加基本类型配置";
      const result = validateBase(baseCheck, value, field);
      if (result) return result;
    }
  }
  return "";
};

// // 参数配置
// const paramsConfig: ObjectCheck[] = [
//   {
//     field: "username",
//     type: "base",
//     required: true,
//     baseCheck: {
//       type: "string",
//       // canNull: true,
//       regExp: /^[a-zA-Z]{5,}$/,
//       message: "username 需为5位及以上纯字母",
//     },
//   },
//   {
//     field: "password",
//     type: "base",
//     required: true,
//     baseCheck: {
//       type: "number",
//       // canNull: true,
//       regExp: /^\d{8,}$/,
//       message: "password应为8位及以上纯数字",
//     },
//   },
//   {
//     field: "manager",
//     type: "base",
//     baseCheck: {
//       type: "boolean",
//     },
//   },
//   {
//     field: "currentRole",
//     type: "object",
//     objectCheck: [
//       {
//         field: "roleId",
//         type: "base",
//         required: true,
//         baseCheck: {
//           type: "string",
//           canNull: true,
//           regExp: /^\d{11}$/,
//           message: "roleId必须位11位纯数字",
//         },
//       },
//       {
//         field: "roleName",
//         type: "base",
//         baseCheck: {
//           type: "string",
//           regExp: /^.{1,10}$/,
//           message: "roleName应为1-10个字符",
//         },
//       },
//       {
//         field: "ids",
//         type: "array",
//         arrayCheck: {
//           type: "base",
//           baseCheck: {
//             type: "string",
//             regExp: /^\d{11}$/,
//             message: "ids项应为11位纯数字",
//           },
//         },
//       },
//     ],
//   },
//   {
//     field: "routerList",
//     type: "array",
//     arrayCheck: {
//       type: "object",
//       objectCheck: [
//         {
//           field: "filePath",
//           type: "base",
//           baseCheck: {
//             type: "string",
//             regExp: /^(\/[a-zA-Z0-9]+)+\.vue$/,
//             message: "请输入正确的filePath",
//           },
//         },
//         {
//           field: "btnPermission",
//           type: "array",
//           arrayCheck: {
//             type: "array",
//             arrayCheck: {
//               type: "base",
//               length: 2,
//               baseCheck: {
//                 type: "number",
//                 regExp: /^\d{2}$/,
//                 message: "二位数组项应为两位数字",
//               },
//             },
//           },
//         },
//       ],
//     },
//   },
// ];
// 参数
// const params = {
//   username: "dongyusheng",
//   password: 12345678,
//   manager: false,
//   currentRole: {
//     roleId: null,
//     roleName: "我和丹丹养了一只小白",
//     ids: ["12345123456", "99999999999"],
//   },
//   routerList: [
//     {
//       filePath: "/views/page/page1/index.vue",
//       btnPermission: [
//         [10, 22],
//         [33, 44],
//       ],
//     },
//   ],
// };
// const validate = validateObject(paramsConfig, params);
// if (validate) logger.log(validate);

// // 参数
// const strs = "123";
// // 参数配置
// const strParamsConfig: BaseCheck = {
//   type: "string",
//   canNull: true,
//   regExp: /^(\d{3}\,)*\d{3}$/,
//   message: "某某id格式错误",
// };
// const validate = validateBase(strParamsConfig, strs, "某某ids");
// if (validate) logger.log(validate);
